package com.guomei.service.exam.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.guomei.bean.Certificate;
import com.guomei.bean.User;
import com.guomei.bean.curse.*;
import com.guomei.bean.exam.IsPassDTO;
import com.guomei.bean.exam.domain.Exam;
import com.guomei.bean.exam.domain.ExamAnswer;
import com.guomei.bean.exam.domain.ExamAnswerDetail;
import com.guomei.bean.exam.domain.ExamEnroll;
import com.guomei.bean.exam.domain.ExamQuestion;
import com.guomei.bean.exam.vo.ExamAnswerVo;
import com.guomei.mapper.UserMapper;
import com.guomei.mapper.curse.*;
import com.guomei.service.CertificateService;
import com.guomei.service.exam.ExamAnswerDetailService;
import com.guomei.service.exam.ExamAnswerService;
import com.guomei.utils.PageData;
import com.guomei.utils.Result;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 考试答卷服务实现类
 */
@Service
@Slf4j
@Transactional
public class ExamAnswerServiceImpl implements ExamAnswerService {
    
    @Resource
    private ExamAnswerMapper examAnswerMapper;
    
    @Resource
    private ExamAnswerDetailMapper examAnswerDetailMapper;

    @Resource
    private CourseMapper courseMapper;
    
    @Resource
    private ExamEnrollMapper examEnrollMapper;
    @Autowired
    private UserMapper userMapper;
    
    @Resource
    private ExamMapper examMapper;
    @Resource
    private ExamQuestionMapper examQuestionMapper;
    
    @Resource
    private ExamAnswerDetailService examAnswerDetailService;

    @Autowired
    private CertificateService certificateService;

    @Override
    public ExamAnswer getById(Long id) {
        if (id == null) {
            return null;
        }
        return examAnswerMapper.selectById(id);
    }

    @Override
    public List<ExamAnswer> getAll() {
        return examAnswerMapper.selectAll();
    }

    @Override
    public Result<?> getByCondition(ExamAnswer examAnswer) {
        PageHelper.startPage(examAnswer.getPageNum(), examAnswer.getPageSize());
        
        List<ExamAnswer> examAnswers = examAnswerMapper.selectByCondition(examAnswer);
        if (examAnswers != null && !examAnswers.isEmpty()){
            for (ExamAnswer answer : examAnswers) {
                Exam exam = examMapper.selectById(answer.getExamId());
                User user = userMapper.selectById(answer.getUserId());
                Course course = courseMapper.selectById(exam.getCourseId());
                if (exam != null && user != null && course != null) {
                    answer.setExamName(exam.getExamName());
                    answer.setUserName(user.getRealName());
                    answer.setCourseType(course.getCourseType());
                    answer.setCourseName(course.getCourseName());
                } else {
                    log.info("考试不存在或用户不存在");
                    continue;
                }
            }
        }
        // 封装分页结果到PageData
        PageData<ExamAnswer> pageData = new PageData<>();
        PageInfo<ExamAnswer> pageInfo = new PageInfo<>(examAnswers);
        pageData.setTotal(pageInfo.getTotal());
        pageData.setData(pageInfo.getList());
        pageData.setPageNum(examAnswer.getPageNum());
        pageData.setPageSize(examAnswer.getPageSize());
        return Result.success(pageData);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean save(ExamAnswer examAnswer) {
        if (examAnswer == null) {
            return false;
        }

        // 设置创建和更新时间
        LocalDateTime now = LocalDateTime.now();
        examAnswer.setCreatedTime(now);
        examAnswer.setUpdatedTime(now);
        
        // 设置默认值
        if (examAnswer.getStatus() == null) {
            examAnswer.setStatus((short) 0); // 0-进行中
        }

        return examAnswerMapper.insert(examAnswer) > 0;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean batchSave(List<ExamAnswer> examAnswers) {
        if (examAnswers == null || examAnswers.isEmpty()) {
            return false;
        }

        LocalDateTime now = LocalDateTime.now();
        for (ExamAnswer examAnswer : examAnswers) {
            // 设置创建和更新时间
            examAnswer.setCreatedTime(now);
            examAnswer.setUpdatedTime(now);
            
            // 设置默认值
            if (examAnswer.getStatus() == null) {
                examAnswer.setStatus((short) 0); // 0-进行中
            }
        }

        return examAnswerMapper.batchInsert(examAnswers) > 0;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean update(ExamAnswer examAnswer) {
        if (examAnswer == null || examAnswer.getId() == null) {
            return false;
        }
        
        // 设置更新时间
        examAnswer.setUpdatedTime(LocalDateTime.now());
        
        return examAnswerMapper.updateById(examAnswer) > 0;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean removeById(Long id) {
        if (id == null) {
            return false;
        }
        return examAnswerMapper.deleteById(id) > 0;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean batchRemove(List<Long> ids) {
        if (ids == null || ids.isEmpty()) {
            return false;
        }
        return examAnswerMapper.batchDelete(ids) > 0;
    }

    @Override
    public List<ExamAnswer> getByExamId(Long examId) {
        if (examId == null) {
            return null;
        }
        return examAnswerMapper.selectByExamId(examId);
    }

    @Override
    public List<ExamAnswer> getByUserId(Long userId) {
        if (userId == null) {
            return null;
        }
        return examAnswerMapper.selectByUserId(userId);
    }

    @Override
    public List<ExamAnswer> getByEnrollId(Long enrollId) {
        if (enrollId == null) {
            return null;
        }
        return examAnswerMapper.selectByEnrollId(enrollId);
    }

    @Override
    public ExamAnswer getByExamIdAndUserId(Long examId, Long userId) {
        if (examId == null || userId == null) {
            return null;
        }
        return examAnswerMapper.selectByExamIdAndUserId(examId, userId);
    }

    @Override
    public ExamAnswer getByEnrollIdAndUserId(Long enrollId, Long userId) {
        if (enrollId == null || userId == null) {
            return null;
        }
        return examAnswerMapper.selectByEnrollIdAndUserId(enrollId, userId);
    }

    @Override
    public List<ExamAnswer> getByStatus(Short status) {
        if (status == null) {
            return null;
        }
        return examAnswerMapper.selectByStatus(status);
    }

    @Override
    public List<ExamAnswer> getByReviewUserId(Long reviewUserId) {
        if (reviewUserId == null) {
            return null;
        }
        return examAnswerMapper.selectByReviewUserId(reviewUserId);
    }

    @Override
    public List<ExamAnswer> getByReviewResult(Short reviewResult) {
        if (reviewResult == null) {
            return null;
        }
        return examAnswerMapper.selectByReviewResult(reviewResult);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean removeByExamId(Long examId) {
        if (examId == null) {
            return false;
        }
        return examAnswerMapper.deleteByExamId(examId) > 0;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean removeByUserId(Long userId) {
        if (userId == null) {
            return false;
        }
        return examAnswerMapper.deleteByUserId(userId) > 0;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean removeByEnrollId(Long enrollId) {
        if (enrollId == null) {
            return false;
        }
        return examAnswerMapper.deleteByEnrollId(enrollId) > 0;
    }

    @Override
    public int countByUserId(Long userId) {
        if (userId == null) {
            return 0;
        }
        return examAnswerMapper.countByUserId(userId);
    }

    @Override
    public int countByExamId(Long examId) {
        if (examId == null) {
            return 0;
        }
        return examAnswerMapper.countByExamId(examId);
    }

    @Override
    public int countByStatus(Short status) {
        if (status == null) {
            return 0;
        }
        return examAnswerMapper.countByStatus(status);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result<?> startExam(Long examId, Long enrollId, Long userId) {
        try {
            // 1. 验证参数
            if (examId == null || enrollId == null || userId == null) {
                return Result.fail("参数不能为空");
            }

            // 2. 检查报名记录
            ExamEnroll examEnroll = examEnrollMapper.selectById(enrollId);
            if (examEnroll == null) {
                return Result.fail("报名记录不存在");
            }

            if (!examEnroll.getUserId().equals(userId)) {
                return Result.fail("无权操作此报名记录");
            }

            if (examEnroll.getPayStatus() != null && examEnroll.getPayStatus() != 1) {
                return Result.fail("请先完成支付");
            }

            // 3. 检查是否已经开始考试
            ExamAnswer existingAnswer = getByEnrollIdAndUserId(enrollId, userId);
            if (existingAnswer != null) {
                if (existingAnswer.getStatus() == 0) {
                    return Result.success("考试已开始", existingAnswer);
                } else if (existingAnswer.getStatus() == 1) {
                    return Result.fail("考试已提交，无法重新开始");
                }
            }

            // 4. 创建答卷记录
            ExamAnswer examAnswer = new ExamAnswer();
            examAnswer.setExamId(examId);
            examAnswer.setEnrollId(enrollId);
            examAnswer.setUserId(userId);
            examAnswer.setStartTime(LocalDateTime.now());
            examAnswer.setStatus((short) 0); // 0-进行中

            boolean success = save(examAnswer);
            if (success) {
                return Result.success("考试开始成功", examAnswer);
            } else {
                return Result.fail("考试开始失败");
            }

        } catch (Exception e) {
            log.error("开始考试失败", e);
            return Result.fail("开始考试失败：" + e.getMessage());
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result<?> submitAnswer(Long answerId, Long userId) {
        try {
            // 1. 验证参数
            if (answerId == null || userId == null) {
                return Result.fail("参数不能为空");
            }

            // 2. 检查答卷记录
            ExamAnswer examAnswer = getById(answerId);
            if (examAnswer == null) {
                return Result.fail("答卷记录不存在");
            }

            if (!examAnswer.getUserId().equals(userId)) {
                return Result.fail("无权操作此答卷");
            }

            if (examAnswer.getStatus() != 0) {
                return Result.fail("答卷状态不正确");
            }
            List<ExamAnswerDetail> answerDetails = new ArrayList<>();
            //进行客观题的评分
            List<ExamAnswerDetail> byAnswerId = examAnswerDetailService.getByAnswerId(answerId);
            List<ExamQuestion> examQuestions = examQuestionMapper.selectByExamId(examAnswer.getExamId());
            if (byAnswerId != null && !byAnswerId.isEmpty()){
                for (ExamAnswerDetail examAnswerDetail : byAnswerId) {
                    for (ExamQuestion examQuestion : examQuestions) {
                        if (examQuestion.getId().equals(examAnswerDetail.getQuestionId())){
                            //主观题跳出该循环
                            if (examQuestion.getQuestionType() != 1){
                                continue;
                            }
                            Integer score = examQuestion.getScore();
                            if (examAnswerDetail.getUserAnswer().equals(examQuestion.getCorrectAnswer())){
                                examAnswerDetail.setScore(score);
                            } else {
                                examAnswerDetail.setScore(0);
                            }
                            answerDetails.add(examAnswerDetail);
                        }
                    }
                }
                examAnswerDetailService.batchScoreAnswer(answerDetails);
            } else {
                return Result.fail("自动评判客观题失败，请联系管理员");
            }
            // 3. 更新答卷状态
            examAnswer.setEndTime(LocalDateTime.now());
            examAnswer.setStatus((short) 1); // 1-已提交

            boolean success = update(examAnswer);
            if (success) {
                return Result.success("答卷提交成功");
            } else {
                return Result.fail("答卷提交失败");
            }

        } catch (Exception e) {
            log.error("提交答卷失败", e);
            return Result.fail("提交答卷失败：" + e.getMessage());
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result<?> reviewAnswer(Long answerId, Long reviewUserId, Short reviewResult, String reviewRemark) {
        try {
            // 1. 验证参数
            if (answerId == null || reviewUserId == null || reviewResult == null) {
                return Result.fail("参数不能为空");
            }

            // 2. 检查答卷记录
            ExamAnswer examAnswer = getById(answerId);
            if (examAnswer == null) {
                return Result.fail("答卷记录不存在");
            }

            if (examAnswer.getStatus() != 1) {
                return Result.fail("答卷状态不正确");
            }

            // 3. 更新答卷状态
            examAnswer.setReviewUserId(reviewUserId);
            examAnswer.setReviewTime(LocalDateTime.now());
            examAnswer.setReviewResult(reviewResult);
            examAnswer.setStatus((short) 2); // 2-已完成审核

            boolean success = update(examAnswer);
            if (success) {
                if (examAnswer.getReviewResult() == 1){
                    Certificate certificate = new Certificate();
                    certificate.setExamId(examAnswer.getExamId());
                    certificate.setUserId(examAnswer.getUserId());
                    certificate.setAnswerId(examAnswer.getId());
                    certificate.setCertNo("CERT-" + System.currentTimeMillis());
                    certificate.setIssueTime(new Date());
                    certificateService.createCertificate(certificate);
                }
                return Result.success("审核完成");
            } else {
                return Result.fail("审核失败");
            }

        } catch (Exception e) {
            log.error("审核答卷失败", e);
            return Result.fail("审核答卷失败：" + e.getMessage());
        }
    }

    @Override
    public Result<?> getAnswerDetail(Long answerId) {
        try {
            // 1. 验证参数
            if (answerId == null) {
                return Result.fail("参数不能为空");
            }

            // 2. 获取答卷信息
            ExamAnswer examAnswer = getById(answerId);
            if (examAnswer == null) {
                return Result.fail("答卷记录不存在");
            }

            // 3. 获取答卷详情
            List<ExamAnswerDetail> answerDetails = examAnswerDetailService.getByAnswerId(answerId);

            // 4. 计算总分
            Integer totalScore = examAnswerDetailService.sumScoreByAnswerId(answerId);

            // 5. 封装返回数据
            java.util.Map<String, Object> result = new java.util.HashMap<>();
            result.put("examAnswer", examAnswer);
            result.put("answerDetails", answerDetails);
            result.put("totalScore", totalScore);

            return Result.success(result);

        } catch (Exception e) {
            log.error("获取答卷详情失败", e);
            return Result.fail("获取答卷详情失败：" + e.getMessage());
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result<?> reviewSubjectiveScores(AnswerReviewDTO reviewDTO) {
        try {
            if (reviewDTO == null || reviewDTO.getAnswerId() == null || reviewDTO.getReviewUserId() == null) {
                return Result.fail("参数不能为空");
            }
            Long answerId = reviewDTO.getAnswerId();
            ExamAnswer examAnswer = getById(answerId);
            if (examAnswer == null) {
                return Result.fail("答卷记录不存在");
            }
            // 1) 批量更新主观题得分
            if (reviewDTO.getItems() != null && !reviewDTO.getItems().isEmpty()) {
                for (AnswerReviewDTO.SubjectiveScoreItem item : reviewDTO.getItems()) {
                    if (item.getQuestionId() == null || item.getScore() == null) {
                        return Result.fail("题目ID与分数不能为空");
                    }
                    ExamAnswerDetail detail = examAnswerDetailMapper.selectByAnswerIdAndQuestionId(answerId, item.getQuestionId());
                    if (detail == null) {
                        return Result.fail("未找到题目对应的答题记录");
                    }
                    detail.setScore(item.getScore());
                    if (item.getRemark() != null) {
                        detail.setReviewRemark(item.getRemark());
                    }
                    detail.setUpdatedTime(LocalDateTime.now());
                    examAnswerDetailMapper.updateById(detail);
                }
            }
            // 2) 分别统计客观题与主观题得分
            Integer objectiveTotal = examAnswerDetailMapper.sumObjectiveScoreByAnswerId(answerId);
            Integer subjectiveTotal = examAnswerDetailMapper.sumSubjectiveScoreByAnswerId(answerId);
            if (objectiveTotal == null) objectiveTotal = 0;
            if (subjectiveTotal == null) subjectiveTotal = 0;
            // 3) 同时达到>=60则更新答卷状态为已完成审核
            if (objectiveTotal >= 60 && subjectiveTotal >= 60) {
                examAnswer.setReviewUserId(reviewDTO.getReviewUserId());
                examAnswer.setReviewTime(LocalDateTime.now());
                examAnswer.setReviewResult((short)1); // 1-通过
                examAnswer.setStatus((short)2); // 已完成审核
                update(examAnswer);
                if (examAnswer.getReviewResult() == 1){
                    Certificate certificate = new Certificate();
                    certificate.setExamId(examAnswer.getExamId());
                    certificate.setUserId(examAnswer.getUserId());
                    certificate.setAnswerId(examAnswer.getId());
                    certificate.setCertNo("CERT-" + System.currentTimeMillis());
                    certificate.setIssueTime(new Date());
                    certificateService.createCertificate(certificate);
                }
            }else{
                examAnswer.setReviewUserId(reviewDTO.getReviewUserId());
                examAnswer.setReviewTime(LocalDateTime.now());
                examAnswer.setReviewResult((short)2); // 2-未通过
                examAnswer.setStatus((short)2); // 已完成审核
                update(examAnswer);
            }
            java.util.Map<String, Object> data = new java.util.HashMap<>();
            data.put("objectiveTotal", objectiveTotal);
            data.put("subjectiveTotal", subjectiveTotal);
            return Result.success("审核完成", data);
        } catch (Exception e) {
            log.error("主观题评分审核失败", e);
            return Result.fail("主观题评分审核失败：" + e.getMessage());
        }
    }

    @Override
    public Result<?> selectIs(List<IsPassDTO> isPassDTOList) {
        ArrayList<HashMap<String, Boolean>> List = new ArrayList<>();
        for (IsPassDTO isPassDTO : isPassDTOList) {
            ExamAnswer examAnswer = new ExamAnswer();
            examAnswer.setExamId(isPassDTO.getExamId());
            examAnswer.setUserId(isPassDTO.getUserId());
            ExamAnswer examAnswer1 = examAnswerMapper.selectByCondition(examAnswer).get(0);
            HashMap<String, Boolean> objectObjectHashMap = new HashMap<>();
            if (examAnswer1 != null && examAnswer1.getReviewResult() == 1){
                objectObjectHashMap.put("isPassed", true);
            } else {
                objectObjectHashMap.put("isPassed", false);
            }
            List.add(objectObjectHashMap);
        }
        return Result.success(List);
    }
}
